package com.lancoo.answer.view.base

import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.os.IBinder
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import androidx.annotation.CallSuper
import androidx.appcompat.app.AppCompatActivity
import androidx.viewbinding.ViewBinding
import com.dylanc.viewbinding.base.inflateBindingWithGeneric
import com.lancoo.answer.listener.SoftKeyBoardListener
import com.lancoo.answer.util.DpUtils.dip2px
import com.lancoo.answer.util.FastClickUtils
import com.lancoo.answer.view.dialog.DialogLoading
import java.lang.reflect.InvocationTargetException

abstract class XBaseActivity<VB : ViewBinding>: AppCompatActivity(){

    lateinit var binding: VB

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        try {
            binding = inflateBindingWithGeneric(layoutInflater)
            setContentView(binding.root)
        } catch (e: NoSuchMethodException) {
            e.printStackTrace()
        } catch (e: IllegalAccessException) {
            e.printStackTrace()
        } catch (e: InvocationTargetException) {
            e.printStackTrace()
        }

        initView()
        changeStatusBarTransparent(this)
        AndroidBug5497Workaround.assistActivity(this)//todo 适配有Edittext的特殊布局
        setSoftKeyBoardListener()//todo 点击软键盘隐藏，强制EditText失去焦点
    }

    private val loadingDialog by lazy { DialogLoading(this) }

    fun startLoad(message: String = "") {
        loadingDialog.setMessage(message)
        loadingDialog.show()
    }

    fun stopLoad() = loadingDialog.dismiss()

    abstract fun initView()

    /*
    * todo 沉浸式状态栏适配
    * */
    private fun changeStatusBarTransparent(activity: AppCompatActivity) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            return
        }
        val window = activity.window
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
            val option = window.decorView.systemUiVisibility or View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            window.decorView.systemUiVisibility = option
            //6.0以上系统支持修改状态栏字体颜色，6.0以下不支持的设为黑色透明背景，突显白色字体
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                window.statusBarColor = Color.parseColor("#00000000")
            }else{
                window.statusBarColor = Color.parseColor("#20000000")
            }
        } else {
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
        }
    }


    /*
    * todo 通过反射获取状态栏高度，默认25dp-->>(适配有有EditText需要调用软键盘上顶活动布局，固定topbar的特殊情况)
    * */
    open fun getStatusBarHeight(): Int {
        var statusBarHeight = dip2px(this, 25f)
        try {
            val clazz = Class.forName("com.android.internal.R\$dimen")
            val `object` = clazz.newInstance()
            val height = clazz.getField("status_bar_height")[`object`].toString().toInt()
            statusBarHeight = this.resources.getDimensionPixelSize(height)
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return statusBarHeight
    }

    /**
     * todo 重写点击事件
     */
    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        if (ev.action == MotionEvent.ACTION_DOWN) {
            //防止短时间内多次点击
            if (FastClickUtils.isFastDoubleClick) {
                return true
            }
            //实现软键盘点击空白处自动回收
            val v = currentFocus //得到当前页面的焦点,ps:有输入框的页面焦点一般会被输入框占据
            if (isShouldHideKeyboard(v, ev)) {
                //判断用户点击的是否是输入框以外的区域
                hideKeyboard(v!!.windowToken) //收起键盘
            }
        }
        return super.dispatchTouchEvent(ev)
    }
    /**
     * 根据EditText所在坐标和用户点击的坐标相对比，来判断是否隐藏键盘，因为当用户点击EditText时则不能隐藏
     */
    open fun isShouldHideKeyboard(v: View?, event: MotionEvent): Boolean {
        if (v != null && v is EditText) {  //判断得到的焦点控件是否包含EditText
            v.clearFocus()//关键，点睛之笔 （哈哈哈）
            val l = intArrayOf(0, 0)
            v.getLocationInWindow(l)
            val left = l[0]
            //得到输入框在屏幕中上下左右的位置
            val top = l[1]
            val bottom: Int = top + v.getHeight()
            val right: Int = left + v.getWidth()
            return !(event.x > left && event.x < right && event.y > top && event.y < bottom)
        }
        // 如果焦点不是EditText则忽略
        return false
    }
    /**
     * 获取InputMethodManager，隐藏软键盘
     */
    open fun hideKeyboard(token: IBinder?) {
        if (token != null) {
            val im: InputMethodManager =
                getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
            im.hideSoftInputFromWindow(token, InputMethodManager.HIDE_NOT_ALWAYS)
        }
    }


    /**
     * todo 添加软键盘监听
     */
    open fun setSoftKeyBoardListener() {
        val softKeyBoardListener = SoftKeyBoardListener(this)
        //软键盘状态监听
        softKeyBoardListener.setListener(object :
            SoftKeyBoardListener.OnSoftKeyBoardChangeListener {
            override fun keyBoardShow(height: Int) {
                //软键盘已经显示，做逻辑
            }

            override fun keyBoardHide(height: Int) {
                //软键盘已经隐藏,做逻辑
                currentFocus?.clearFocus()
            }
        })
    }

    @CallSuper
    override fun onDestroy() {
        super.onDestroy()
    }

}